from typing import Dict, Optional
from fastapi import FastAPI, Path, Query, Body
import uvicorn
from pydantic import BaseModel

app = FastAPI()

'''
    参数类型指定为 Pydantic Model，这样 FastAPI 会解析它为一个 Request Body，
    如果是单类型（int, float, str ,bool） 如何成为body 的一部分，通过Body函数即可。
    
    Body的主要作用：可以将单类型的参数成为 Request Body 的一部分，即从查询参数变成请求体参数
'''


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


class User(BaseModel):
    username: str
    full_name: Optional[str] = None


@app.post('/items/{item_id}')
async def update_item(item_id: int, item: Item, user: User, importance: int = Body(...)):
    results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
    return results



# Body() 中的 embed 参数
# 当函数只有一个参数指定了 Pydantic Model 且没有其他 Body 参数时，传参的时候请求体可以不指定参数名
#  如果我想指定请求体的字段名该怎么办呢？ embed = True

@app.post("/items2/{item_id}")
async def update_item(
        *,
        item_id: int,
        # 将 embed 设置为 True
        item: Item = Body(..., embed=True)):
    results = {"item_id": item_id, "item": item}
    return results


'''
请求体参数必须 {
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    }
}  才行，否则会报错

'''



if __name__ == '__main__':
    uvicorn.run(app='main:app', host='127.0.0.1', port=8000, reload=True, debug=True)

if __name__ == '__main__':
    uvicorn.run(app='main:app', host='127.0.0.1', port=8000, reload=True, debug=True)
